home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / bones.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  9.9 KB  |  408 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)bones.c    3.1    93/06/05    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "lev.h"
  7.  
  8. #ifdef MFLOPPY
  9. extern char bones[];    /* from files.c */
  10. extern long bytes_counted;
  11. #endif
  12.  
  13. static boolean FDECL(no_bones_level, (d_level *));
  14. #ifdef TUTTI_FRUTTI
  15. static void FDECL(goodfruit, (int));
  16. #endif
  17. static void FDECL(resetobjs,(struct obj *,BOOLEAN_P));
  18. static void FDECL(drop_upon_death, (struct monst *, struct obj *));
  19.  
  20. static boolean
  21. no_bones_level(lev)
  22. d_level *lev;
  23. {
  24.     extern d_level save_dlevel;        /* in do.c */
  25.     s_level *sptr;
  26.  
  27.     if (ledger_no(&save_dlevel)) assign_level(lev, &save_dlevel);
  28.  
  29.     return (boolean)(((sptr = Is_special(lev)) && !sptr->boneid)
  30.         || !dungeons[lev->dnum].boneid
  31.            /* no bones on the last or multiway branch levels */
  32.            /* in any dungeon (level 1 isn't multiway).       */
  33.         || Is_botlevel(lev) || (Is_branchlev(lev) && lev->dlevel > 1)
  34.            /* no bones in the invocation level               */
  35.         || (In_hell(lev) && lev->dlevel == dunlevs_in_dungeon(lev) - 1)
  36.         );
  37. }
  38.  
  39. #ifdef TUTTI_FRUTTI
  40. static void
  41. goodfruit(id)
  42. int id;
  43. {
  44.     register struct fruit *f;
  45.  
  46.     for(f=ffruit; f; f=f->nextf) {
  47.         if(f->fid == -id) {
  48.             f->fid = id;
  49.             return;
  50.         }
  51.     }
  52. }
  53. #endif
  54.  
  55. static void
  56. resetobjs(ochain,restore)
  57. struct obj *ochain;
  58. boolean restore;
  59. {
  60.     struct obj *otmp;
  61.  
  62.     for (otmp = ochain; otmp; otmp = otmp->nobj) {
  63.         if (otmp->cobj)
  64.             resetobjs(otmp->cobj,restore);
  65.  
  66.         if (((otmp->otyp != CORPSE || otmp->corpsenm < PM_ARCHEOLOGIST)
  67.             && otmp->otyp != STATUE)
  68.             && (!otmp->oartifact ||
  69.                 (exist_artifact(otmp->otyp,ONAME(otmp)) && restore))) {
  70.             otmp->oartifact = 0;
  71.             otmp->onamelth = 0;
  72.             *ONAME(otmp) = '\0';
  73.         } else if (otmp->oartifact && restore)
  74.             artifact_exists(otmp,ONAME(otmp),TRUE);
  75.         if (!restore) {
  76.             /* resetting the o_id's after getlev has carefully
  77.              * created proper new ones via restobjchn is a Bad
  78.              * Idea */
  79.             otmp->o_id = 0;
  80.             if(objects[otmp->otyp].oc_uses_known) otmp->known = 0;
  81.             otmp->dknown = otmp->bknown = 0;
  82.             otmp->rknown = 0;
  83.             otmp->invlet = 0;
  84. #ifdef TUTTI_FRUTTI
  85.             if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
  86.             else
  87. #endif
  88. #ifdef MAIL
  89.             if (otmp->otyp == SCR_MAIL) otmp->spe = 1;
  90.             else
  91. #endif
  92. #ifdef POLYSELF
  93.             if (otmp->otyp == EGG) otmp->spe = 0;
  94.             else
  95. #endif
  96.             if (otmp->otyp == AMULET_OF_YENDOR) {
  97.                 /* no longer the real Amulet */
  98.                 otmp->otyp = FAKE_AMULET_OF_YENDOR;
  99.                 curse(otmp);
  100.             } else if (otmp->otyp == CANDELABRUM_OF_INVOCATION) {
  101.                 otmp->otyp = WAX_CANDLE;
  102.                 otmp->age = 50L;  /* assume used */
  103.                 if (otmp->spe > 0)
  104.                 otmp->quan = (long)otmp->spe;
  105.                 otmp->lamplit = 0;
  106.                 otmp->spe = 0;
  107.                 otmp->owt = weight(otmp);
  108.             } else if (otmp->otyp == BELL_OF_OPENING) {
  109.                 otmp->otyp = BELL;
  110.                 curse(otmp);
  111.             } else if (otmp->otyp == SPE_BOOK_OF_THE_DEAD) {
  112.                 otmp->otyp = SPE_BLANK_PAPER;
  113.                 curse(otmp);
  114. #ifdef MULDGN
  115.             } else if (is_quest_artifact(otmp)) {
  116.                 /*
  117.                  * never leave our own quest artifact among the
  118.                  * bones; others (via wishing) might remain though
  119.                  */
  120.              /* artifact_unexist(otmp); */
  121.                 otmp->oartifact = 0;
  122.                 ONAME(otmp)[0] = '\0';
  123. #endif
  124.             }
  125.         }
  126.     }
  127. }
  128.  
  129. static void
  130. drop_upon_death(mtmp, cont)
  131. struct monst *mtmp;
  132. struct obj *cont;
  133. {
  134.     struct obj *otmp = invent;
  135.     while(otmp) {
  136.         otmp->owornmask = 0;
  137.         otmp->lamplit = 0;
  138. #ifdef TUTTI_FRUTTI
  139.         if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
  140. #endif
  141.         if(rn2(5)) curse(otmp);
  142.         if(!mtmp && !cont) place_object(otmp, u.ux, u.uy);
  143.         if(!otmp->nobj) {
  144.             if (mtmp) {
  145.                 otmp->nobj = mtmp->minvent;
  146.                 mtmp->minvent = invent;
  147.             } else if (cont) {
  148.                 otmp->nobj = cont->cobj;
  149.                 cont->cobj = invent;
  150.             } else {
  151.                 otmp->nobj = fobj;
  152.                 fobj = invent;
  153.             }
  154.             invent = 0;    /* superfluous */
  155.             break;
  156.         }
  157.         otmp = otmp->nobj;
  158.     }
  159.     if(u.ugold) {
  160.         if (mtmp) mtmp->mgold = u.ugold;
  161.         else mkgold(u.ugold, u.ux, u.uy);
  162.     }
  163. }
  164.  
  165. /* save bones and possessions of a deceased adventurer */
  166. void
  167. savebones()
  168. {
  169.     register int fd, x, y;
  170.     register struct trap *ttmp;
  171.     register struct monst *mtmp, *mtmp2;
  172. #ifdef TUTTI_FRUTTI
  173.     struct fruit *f;
  174. #endif
  175.     char c, *bonesid;
  176.  
  177.     if(ledger_no(&u.uz) <= 0 || ledger_no(&u.uz) > maxledgerno()) return;
  178.     if(no_bones_level(&u.uz)) return; /* no bones for specific levels */
  179.     if(!Is_branchlev(&u.uz)) {
  180.         /* no bones on non-branches with portals */
  181.         for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
  182.         if (ttmp->ttyp == MAGIC_PORTAL) return;
  183.     }
  184.  
  185.     if(depth(&u.uz) <= 0 ||        /* bulletproofing for endgame */
  186.        (!rn2(1 + (depth(&u.uz)>>2)) /* fewer ghosts on low levels */
  187. #ifdef WIZARD
  188.         && !wizard
  189. #endif
  190.         )) return;
  191. #ifdef EXPLORE_MODE
  192.     /* don't let multiple restarts generate multiple copies of objects
  193.      * in bones files */
  194.     if(discover) return;
  195. #endif
  196.  
  197.     fd = open_bonesfile(&u.uz, &bonesid);
  198.     if (fd >= 0) {
  199.         (void) close(fd);
  200.         compress_bonesfile();
  201. #ifdef WIZARD
  202.         if(wizard)
  203.             pline("Bones file already exists.");
  204. #endif
  205.         return;
  206.     }
  207.  
  208. #ifdef WALKIES
  209.     unleash_all();
  210. #endif
  211.     /* in case these characters are not in their home bases */
  212.     mtmp2 = fmon;
  213.     while((mtmp = mtmp2)) {
  214.         mtmp2 = mtmp->nmon;
  215.         if(mtmp->iswiz || mtmp->data == &mons[PM_MEDUSA]) mongone(mtmp);
  216.     }
  217. #ifdef TUTTI_FRUTTI
  218.     /* mark all fruits as nonexistent; when we come to them we'll mark
  219.      * them as existing (using goodfruit())
  220.      */
  221.     for(f=ffruit; f; f=f->nextf) f->fid = -f->fid;
  222. #endif
  223.  
  224.     /* check iron balls separately--maybe they're not carrying it */
  225.     if (uball) uball->owornmask = uchain->owornmask = 0;
  226.  
  227.     /* dispose of your possessions, usually cursed */
  228.     if (u.ugrave_arise == -2) {
  229.         struct obj *otmp;
  230.  
  231.         /* embed your possessions in your statue */
  232.         otmp = mk_named_object(STATUE,
  233. #ifdef POLYSELF
  234.                     u.mtimedone ? uasmon :
  235. #endif
  236.                     player_mon(), 
  237.                     u.ux, u.uy, plname,
  238.                     (int)strlen(plname));
  239.         if (!otmp) return;
  240.         drop_upon_death(mtmp = (struct monst *)0, otmp);
  241.     } else if (u.ugrave_arise == -1) {
  242.         /* drop everything */
  243.         drop_upon_death((struct monst *)0, (struct obj *)0);
  244.         /* trick makemon() into allowing monster creation
  245.          * on your location
  246.          */
  247.         in_mklev = TRUE;
  248.         mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy);
  249.         in_mklev = FALSE;
  250.         if (!mtmp) return;
  251.         Strcpy((char *) mtmp->mextra, plname);
  252.     } else {
  253.         /* give your possessions to the monster you become */
  254.         in_mklev = TRUE;
  255.         mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy);
  256.         in_mklev = FALSE;
  257.         if (!mtmp) return;
  258.         mtmp = christen_monst(mtmp, plname);
  259.         newsym(u.ux, u.uy);
  260.         Your("body rises from the dead as %s...",
  261.             an(mons[u.ugrave_arise].mname));
  262.         display_nhwindow(WIN_MESSAGE, FALSE);
  263.         drop_upon_death(mtmp, (struct obj *)0);
  264. #ifdef MUSE
  265.         m_dowear(mtmp, TRUE);
  266. #endif
  267.     }
  268.     if (mtmp) {
  269.         mtmp->m_lev = (u.ulevel ? u.ulevel : 1);
  270.         mtmp->mhp = mtmp->mhpmax = u.uhpmax;
  271.         mtmp->msleep = 1;
  272.     }
  273.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  274.         resetobjs(mtmp->minvent,FALSE);
  275.         mtmp->m_id = 0;
  276.         mtmp->mlstmv = 0L;
  277.         if(mtmp->mtame) mtmp->mtame = mtmp->mpeaceful = 0;
  278.     }
  279.     for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
  280.         ttmp->tseen = 0;
  281.     }
  282.     resetobjs(fobj,FALSE);
  283.     resetobjs(level.buriedobjlist, FALSE);
  284.  
  285.     /* Clear all memory from the level. */
  286.     for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) {
  287.         levl[x][y].seen = levl[x][y].waslit = 0;
  288.         levl[x][y].glyph = cmap_to_glyph(S_stone);
  289.     }
  290.  
  291.     fd = create_bonesfile(&u.uz, &bonesid);
  292.     if(fd < 0) {
  293. #ifdef WIZARD
  294.         if(wizard)
  295.             pline("Cannot create bones file - create failed");
  296. #endif
  297.         return;
  298.     }
  299.  
  300.     bufon(fd);
  301. #ifdef MFLOPPY  /* check whether there is room */
  302.     savelev(fd, ledger_no(&u.uz), COUNT_SAVE);
  303. # ifdef TUTTI_FRUTTI
  304.     /* this is in the opposite order from the real save, but savelev()
  305.      * initializes bytes_counted to 0, so doing savefruitchn() first is
  306.      * useless; the extra bflush() at the end of savelev() may increase
  307.      * bytes_counted by a couple over what the real usage will be
  308.      */
  309.     savefruitchn(fd, COUNT_SAVE);
  310.     bflush(fd);
  311. # endif
  312.     if (bytes_counted > freediskspace(bones)) {    /* not enough room */
  313. # ifdef WIZARD
  314.         if (wizard)
  315.             pline("Insufficient space to create bones file.");
  316. # endif
  317.         (void) close(fd);
  318.         delete_bonesfile(&u.uz);
  319.         return;
  320.     }
  321.     co_false();    /* make sure bonesid and savefruitchn get written */
  322. #endif /* MFLOPPY */
  323.  
  324.     c = (char) (strlen(bonesid) + 1);
  325.     bwrite(fd, (genericptr_t) &c, sizeof c);
  326.     bwrite(fd, (genericptr_t) bonesid, (unsigned) c);    /* DD.nnn */
  327. #ifdef TUTTI_FRUTTI
  328.     savefruitchn(fd, WRITE_SAVE | FREE_SAVE);
  329. #endif
  330.     savelev(fd, ledger_no(&u.uz), WRITE_SAVE | FREE_SAVE);
  331.     bclose(fd);
  332.     compress_bonesfile();
  333. }
  334.  
  335. int
  336. getbones()
  337. {
  338.     register int fd;
  339.     register int ok;
  340.     char c, *bonesid, oldbonesid[10];
  341.  
  342. #ifdef EXPLORE_MODE
  343.     if(discover)        /* save bones files for real games */
  344.         return(0);
  345. #endif
  346.     /* wizard check added by GAN 02/05/87 */
  347.     if(rn2(3)    /* only once in three times do we find bones */
  348. #ifdef WIZARD
  349.         && !wizard
  350. #endif
  351.         ) return(0);
  352.     if(no_bones_level(&u.uz)) return(0);
  353.     fd = open_bonesfile(&u.uz, &bonesid);
  354.     if (fd < 0) return(0);
  355.  
  356.     if((ok = uptodate(fd)) != 0){
  357. #ifdef WIZARD
  358.         if(wizard)  {
  359.             if(yn("Get bones?") == 'n') {
  360.                 (void) close(fd);
  361.                 compress_bonesfile();
  362.                 return(0);
  363.             }
  364.         }
  365. #endif
  366.         minit();    /* ZEROCOMP */
  367.         mread(fd, (genericptr_t) &c, sizeof c);    /* length incl. '\0' */
  368.         mread(fd, (genericptr_t) oldbonesid, (unsigned) c); /* DD.nnn */
  369.         if (strcmp(bonesid, oldbonesid)) {
  370. #ifdef WIZARD
  371.             if (wizard) {
  372.                 pline("This is bones level '%s', not '%s'!",
  373.                     oldbonesid, bonesid);
  374.                 ok = FALSE;    /* won't die of trickery */
  375.             }
  376. #endif
  377.             trickery();
  378.         } else {
  379.             register struct monst *mtmp;
  380.  
  381.             getlev(fd, 0, 0, TRUE);
  382.  
  383.             /* to correctly reset named artifacts on the level */
  384.             for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  385.                 resetobjs(mtmp->minvent,TRUE);
  386.             resetobjs(fobj,TRUE);
  387.             resetobjs(level.buriedobjlist,TRUE);
  388.         }
  389.     }
  390.     (void) close(fd);
  391.  
  392. #ifdef WIZARD
  393.     if(wizard) {
  394.         if(yn("Unlink bones?") == 'n') {
  395.             compress_bonesfile();
  396.             return(ok);
  397.         }
  398.     }
  399. #endif
  400.     if (!delete_bonesfile(&u.uz)) {
  401.         pline("Cannot unlink bones.");
  402.         return(0);
  403.     }
  404.     return(ok);
  405. }
  406.  
  407. /*bones.c*/
  408.